package com.weijian.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.weijian.common.BusinessException;
import com.weijian.dal.entity.CartItem;
import com.weijian.dal.entity.Course;
import com.weijian.dal.mapper.CartItemMapper;
import com.weijian.dal.mapper.CourseMapper;
import com.weijian.dal.dto.cart.AddCartRequest;
import com.weijian.dal.dto.cart.CartItemDTO;
import com.weijian.dal.dto.cart.UpdateCartRequest;
import com.weijian.service.CartService;
import com.weijian.util.RedisKeyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 购物车服务实现类
 *
 * @author weijian
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CartServiceImpl implements CartService {

    private final CartItemMapper cartItemMapper;
    private final CourseMapper courseMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    private static final long CART_TTL_DAYS = 7;

    @Override
    @Transactional
    public CartItemDTO addToCart(Long userId, AddCartRequest request) {
        // 检查课程是否存在
        Course course = courseMapper.selectById(request.getCourseId());
        if (course == null) {
            throw new BusinessException("课程不存在");
        }

        // 查询未删除的记录，检查是否已存在该课程
        CartItem existingItem = cartItemMapper.findByUserIdAndCourseId(userId, request.getCourseId());

        if (existingItem != null) {
            // 已存在且未删除，增加数量
            existingItem.setQuantity(existingItem.getQuantity() + request.getQuantity());
            cartItemMapper.updateById(existingItem);
            
            // 清除缓存
            clearCartCache(userId);
            return convertToDTO(existingItem);
        }

        // 创建新的购物车商品
        CartItem cartItem = new CartItem();
        cartItem.setUserId(userId);
        cartItem.setCourseId(request.getCourseId());
        cartItem.setCourseTitle(course.getTitle());
        cartItem.setCourseCover(course.getCoverImage());
        cartItem.setCoursePrice(course.getPrice());
        cartItem.setQuantity(request.getQuantity());
        cartItem.setSelected(true);
        cartItem.setCourseLevel(course.getLevel());
        cartItem.setCourseDuration(course.getDuration());

        cartItemMapper.insert(cartItem);

        // 清除缓存
        clearCartCache(userId);

        return convertToDTO(cartItem);
    }

    @Override
    public List<CartItemDTO> getCartList(Long userId) {
        String cacheKey = RedisKeyUtil.getCartKey(userId);

        // 先从缓存获取
        List<CartItemDTO> cachedList = (List<CartItemDTO>) redisTemplate.opsForValue().get(cacheKey);
        if (cachedList != null) {
            log.debug("从Redis缓存获取购物车列表，用户ID: {}", userId);
            return cachedList;
        }

        // 缓存未命中，从数据库获取
        List<CartItem> cartItems = cartItemMapper.findByUserId(userId);
        List<CartItemDTO> cartItemDTOs = cartItems.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        // 存入缓存
        if (!cartItemDTOs.isEmpty()) {
            redisTemplate.opsForValue().set(cacheKey, cartItemDTOs, CART_TTL_DAYS, TimeUnit.DAYS);
            log.debug("购物车列表存入Redis缓存，用户ID: {}", userId);
        }

        return cartItemDTOs;
    }

    @Override
    @Transactional
    public CartItemDTO updateCartItem(Long userId, UpdateCartRequest request) {
        CartItem cartItem = cartItemMapper.selectById(request.getId());
        if (cartItem == null) {
            throw new BusinessException("购物车商品不存在");
        }

        if (!cartItem.getUserId().equals(userId)) {
            throw new BusinessException("无权操作他人的购物车");
        }

        if (request.getQuantity() != null) {
            cartItem.setQuantity(request.getQuantity());
        }
        if (request.getSelected() != null) {
            cartItem.setSelected(request.getSelected());
        }

        cartItemMapper.updateById(cartItem);

        // 清除缓存
        clearCartCache(userId);

        return convertToDTO(cartItem);
    }

    @Override
    @Transactional
    public void removeFromCart(Long userId, Long courseId) {
        CartItem cartItem = cartItemMapper.findByUserIdAndCourseId(userId, courseId);
        if (cartItem == null) {
            throw new BusinessException("购物车商品不存在");
        }

        cartItemMapper.deleteById(cartItem.getId());

        // 清除缓存
        clearCartCache(userId);
    }

    @Override
    @Transactional
    public void clearCart(Long userId) {
        LambdaQueryWrapper<CartItem> wrapper = Wrappers.lambdaQuery(CartItem.class)
                .eq(CartItem::getUserId, userId);

        cartItemMapper.delete(wrapper);

        // 清除缓存
        clearCartCache(userId);
    }

    @Override
    @Transactional
    public CartItemDTO selectCartItem(Long userId, Long cartItemId, Boolean selected) {
        CartItem cartItem = cartItemMapper.selectById(cartItemId);
        if (cartItem == null) {
            throw new BusinessException("购物车商品不存在");
        }

        if (!cartItem.getUserId().equals(userId)) {
            throw new BusinessException("无权操作他人的购物车");
        }

        cartItem.setSelected(selected);
        cartItemMapper.updateById(cartItem);

        // 清除缓存
        clearCartCache(userId);

        return convertToDTO(cartItem);
    }

    @Override
    public List<CartItemDTO> getSelectedItems(Long userId) {
        List<CartItem> selectedItems = cartItemMapper.findSelectedByUserId(userId);
        return selectedItems.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public int getCartItemCount(Long userId) {
        return cartItemMapper.countByUserId(userId);
    }

    /**
     * 清除购物车缓存
     */
    private void clearCartCache(Long userId) {
        String cartKey = RedisKeyUtil.getCartKey(userId);
        String countKey = RedisKeyUtil.getCartCountKey(userId);
        redisTemplate.delete(cartKey);
        redisTemplate.delete(countKey);
        log.info("清除购物车缓存，用户ID: {}", userId);
    }

    /**
     * 实体类转换为DTO
     */
    private CartItemDTO convertToDTO(CartItem cartItem) {
        return BeanUtil.copyProperties(cartItem, CartItemDTO.class);
    }
}